package plantshop.view.listeners;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.swing.event.MouseInputListener;

import plantshop.controller.moves.CustomerBuyRequestMove;
import plantshop.controller.moves.PlantBuyMove;
import plantshop.controller.moves.PlantDragMove;
import plantshop.model.Customer;
import plantshop.model.Display;
import plantshop.model.Game;
import plantshop.model.Location;
import plantshop.model.Store;
import plantshop.model.plants.JapaneseBarberry;
import plantshop.model.plants.Plant;
import plantshop.view.View;

public class TutorialMouseListener implements MouseInputListener, Serializable{
	private static final long serialVersionUID = 5181717199063909808L;
	private Display startDisplay;
	private int startIndex;
	private Plant plantBeingDragged;
	private View view;
	private Game game;
	private State state;
	private Location oldLoc;
	private int tutorialStage = 0;
	
	public final static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	public final static int frameWidth = screenSize.width;
   	public final static int frameHeight = screenSize.height;
   	public final static double xscale = frameWidth/1600.0;
   	public final static double yscale = frameHeight/900.0;
	private int SkipButtonX = (int) (1348*xscale);
	private int SkipButtonY = (int) (20*yscale);
	private int SkipButtonHeight = (int) (50*yscale);


	private int dispEnd;
	private int endIndex;

	enum State{
		NORMAL,
		CLICK,
		DRAG,
		SEEDMENU
	}

	public TutorialMouseListener(View view, Game game){
		this.view = view;
		this.game = game;
	}

	@Override
	public void mouseClicked(MouseEvent e) {

	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// I don't think we want anything  to happen in this method

	}

	@Override
	public void mouseExited(MouseEvent e) {
		// I don't think we want anything  to happen in this method

	}

	@Override
	public void mousePressed(MouseEvent e) {
		startDisplay = StoreMouseListener.findPlot(e.getPoint());
		if(startDisplay != null){
			startIndex = StoreMouseListener.findLocationInPlot(e.getPoint());
			if(startDisplay.getPlant(startIndex) != null && startDisplay.getPlant(startIndex).isGrown()){
				plantBeingDragged = startDisplay.getPlant(startIndex);

			}
			if(plantBeingDragged != null)
				oldLoc = plantBeingDragged.getLoc().clone();
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {

		if(state != State.SEEDMENU){
			if (e.getPoint().x > SkipButtonX && e.getPoint().y > (SkipButtonY - SkipButtonHeight)){
				tutorialStage = 6;
			}
			Display endDisplay = StoreMouseListener.findPlot(e.getPoint());
			Customer customer = StoreMouseListener.findCustomer(e.getPoint());
			if(endDisplay == null && plantBeingDragged != null && customer == null){
				plantBeingDragged.setLoc(oldLoc.getX(), oldLoc.getY());
				view.repaint();
			}
			else if(endDisplay != null){
				int endIndex = StoreMouseListener.findLocationInPlot(e.getPoint());
				boolean whereStart=false, whereEnd=false;
				int dispStart=-1, dispEnd=-1;

				int i = 0;
				for(Display d:view.getGame().getStore().getFront()){
					if(startDisplay == d){
						whereStart = true;
						dispStart = i;
					}
					if(endDisplay == d){
						whereEnd = true;
						dispEnd = i;
					}
					i++;	
				}

				i = 0;
				for(Display d:view.getGame().getStore().getBack()){
					if(startDisplay == d){
						whereStart = false;
						dispStart = i;
					}
					if(endDisplay == d){
						whereEnd = false;
						dispEnd = i;
					}
					i++;	
				}
				if(endIndex==0 && tutorialStage == 2){
					game.getStore().getBack().get(0).getPlant(endIndex).grow();
					tutorialStage++;
				}
				if((startDisplay != endDisplay || startIndex != endIndex) && plantBeingDragged != null && endDisplay.getPlant(endIndex) == null && tutorialStage == 3){
					new PlantDragMove(whereStart, dispStart, startIndex, whereEnd, dispEnd, endIndex).execute(game);
					tutorialStage++;
				}
				else if(!whereEnd && endDisplay.getPlant(endIndex) == null && endIndex == 0 && tutorialStage == 0){
					state = State.SEEDMENU;
					view.buyMenu();
					this.endIndex=endIndex;
					this.dispEnd = dispEnd;
					tutorialStage++;
				}
				else if (plantBeingDragged != null)
					plantBeingDragged.setLoc(oldLoc.getX(), oldLoc.getY());
			}
			else if(tutorialStage == 5){
				tutorialStage++;
			}
			else if(customer != null && customer.getDesiredPlant().getDominant() != -1 && !customer.isLeaving() && tutorialStage == 4)
			{
				boolean whereStart=false;
				int dispStart=-1;

				int i = 0;
				for(Display d:view.getGame().getStore().getFront()){
					if(startDisplay == d){
						whereStart = true;
						dispStart = i;
					}
					i++;	
				}

				i = 0;
				for(Display d:view.getGame().getStore().getBack()){
					if(startDisplay == d){
						whereStart = false;
						dispStart = i;
					}
					i++;	
				}
				if(plantBeingDragged != null)
				{
					new CustomerBuyRequestMove(whereStart, dispStart, startIndex, customer).execute(game);
					tutorialStage++;
				}
			}
			else if (plantBeingDragged != null)
			{
				plantBeingDragged.setLoc(oldLoc.getX(), oldLoc.getY());
			}
			plantBeingDragged = null;
			startDisplay = null;
		}
		else if(tutorialStage == 1){
			int buyIndex = StoreMouseListener.findSeedInMenu(e.getPoint());
			if(buyIndex==1){
				new PlantBuyMove(dispEnd, endIndex, new JapaneseBarberry()).execute(game);
				state = State.NORMAL;
				tutorialStage++;
				view.buyMenuEnd();
				view.repaint();
			}
		}
		view.repaint();
	}


	@Override
	public void mouseDragged(MouseEvent arg0) {
		Point p = arg0.getPoint();
		if(plantBeingDragged != null)
			plantBeingDragged.setLoc(p.x-50, p.y-50);
		view.repaint();
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// I don't think we want anything  to happen in this method
	}
	
	public boolean done(){
		if(tutorialStage == 6){
			tutorialStage++;
			return true;
		}
		return false;
	}
	
	public int getTutorialStage(){
		return tutorialStage;
	}

}

